/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simple;

import algorithm.AlgorithmErrorException;
import algorithm.Genotype;
import algorithm.Individual;
import simple.Factory;
import algorithm.SingleOperator;

/**
 *
 * @author vermaak
 */
public class BitStringMutationOperator implements SingleOperator {

    private double fractionToMutate;

    public BitStringMutationOperator(double fractioToMutate) {
        this.fractionToMutate = fractioToMutate;
    }

    public Individual operate(Individual individual) throws AlgorithmErrorException {
        Genotype genotype = individual.getGenotype();
        if (!(genotype instanceof BitStringGenotype)) {
            throw new AlgorithmErrorException("Only operates on bitstrings.");
        }

        BitStringGenotype bsg = (BitStringGenotype) genotype;
        int nMutations = (int) fractionToMutate * bsg.getLength();
        if (nMutations == 0) {
            nMutations = 1;
        }

        BitStringGenotype newGeno;
        try {
             newGeno = (BitStringGenotype) bsg.clone();
        } catch (Exception e) {
            throw new AlgorithmErrorException("Could not clone bitstring");
        }
        for (int i = 0; i < nMutations; ++i) {
            int index = (int) (Math.random() * bsg.getLength());
            newGeno.flipBit(index);
        }
        
        return Factory.createIndividual(individual.getClass(), newGeno);
    }
}
